﻿using SlamDunk.CMS.Handler;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace SlamDunk.CMS.Controllers.Admin
{
    /// <summary>
    /// 栏目控制器
    /// </summary>
    public class ChannelController : BaseController
    {
        #region 00.实例化业务层对象
        /// <summary>
        /// 实例化业务层对象
        /// </summary>
        private readonly BLL.ChannelBll ChannelBll = BLL.ChannelBll.CreateInstance();
        #endregion

        #region 01.加载视图
        /// <summary>
        /// 加载视图
        /// </summary>
        /// <returns>视图</returns>
        public ActionResult Index()
        {
            return View();
        }
        #endregion

        #region 02.加载列表
        /// <summary>
        /// 加载栏目树
        /// </summary>
        /// <returns>栏目列表树形集合</returns>
        public ActionResult List()
        {
            //1.接收EasyUI请求
            int pId = Request["id"] == null ? 0 : int.Parse(Request["id"]);
            //2.查询所有栏目，根据PId生序排列
            List<Model.Channel> channelList = ChannelBll.GetModelList().OrderBy(x => x.Sort).ToList();
            //3.将栏目集合转换为树形
            List<Model.TreeModel> treeList = OperateContext.Current.ChannelListToTree(channelList, 0);
            //4.返回Json字符串
            return Json(treeList, JsonRequestBehavior.AllowGet);
        }
        #endregion

        #region 03.添加——加载视图
        /// <summary>
        /// 添加——加载视图
        /// </summary>
        /// <param name="id">父Id</param>
        /// <returns>添加视图</returns>
        public ActionResult Add(int id)
        {
            //接收客户端提供的父Id，根据Id查询Name，并赋值给ViewBag
            ViewBag.PId = id;
            ViewBag.PName = ChannelBll.GetModel(id).ChannelName;
            return View();
        }
        #endregion

        #region 04.添加——提交添加
        /// <summary>
        /// 添加——提交添加
        /// </summary>
        /// <param name="model">视图模型</param>
        /// <returns>JsonModel</returns>
        public ActionResult AddConfirm(Model.ChannelView model)
        {
            //校验模型
            if (ModelState.IsValid)
            {
                //1.转换数据模型
                Model.Channel dataModel = model.ToDataModel();
                //2.获取添加后的数据模型
                Model.Channel newModel = ChannelBll.Add(dataModel);
                //3.非空校验
                if (newModel != null)
                {
                    return OperateContext.Current.JsonModel(1, "添加成功！");
                }
                else
                {
                    return OperateContext.Current.JsonModel(0, "添加失败！");
                }
            }
            else    //模型校验失败
            {
                return OperateContext.Current.JsonModel(0, "您输入的数据有误，请重试！");
            }
        }
        #endregion

        #region 05.删除单个栏目及其所有下级栏目——递归
        /// <summary>
        /// 删除单行
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>JsonModel</returns>
        public ActionResult DeleteSingle(int id)
        {
            try             //涉及外键关联，须处理异常
            {
                //1.查询该实体对象是否存在
                Model.Channel model = ChannelBll.GetModel(id);
                if (model == null)
                {
                    return OperateContext.Current.JsonModel(0, "该栏目不存在！");
                }
                else //2.如果存在，则递归删除
                {
                    DeleteRecursion(id);     //删除给定栏目以及其所有下级栏目
                    //重新生成整站
                    return OperateContext.Current.JsonModel(1, "删除成功！");
                }
            }
            catch (Exception ex)
            {
                //写入日志

                //返回客户端错误消息
                return OperateContext.Current.JsonModel(0, ex.Message);
            }
        }
        /// <summary>
        /// 递归删除给定栏目及其所有下级栏目
        /// </summary>
        /// <param name="id">要删除的栏目Id</param>
        private void DeleteRecursion(int id)
        {
            //1.根据给定栏目Id获取所有下级栏目
            List<Model.Channel> list = ChannelBll.GetModelList(id);
            if (list.Count > 0)
            {
                //2.遍历下级栏目
                foreach (Model.Channel channel in list)
                {
                    DeleteRecursion(channel.Id);      //递归
                }
            }
            //3.删除给定部栏目及下级栏目
            ChannelBll.PhysicalDelete(id);
        }
        #endregion

        #region 06.删除选中的栏目
        /// <summary>
        /// 删除选中的栏目
        /// </summary>
        /// <param name="selectedIds">选中树节点的Id</param>
        /// <returns>JsonModel</returns>
        public ActionResult DeleteSelected(string selectedIds)
        {
            try             //涉及多次类型转换与外键关系等操作，应处理异常
            {
                //1.处理前台选中的所有要删除的实体Id信息
                List<int> idList = selectedIds.Split(',').Select(x => int.Parse(x)).ToList();
                //2.执行批量删除操作
                idList.ForEach(x => ChannelBll.PhysicalDelete(x));
                return OperateContext.Current.JsonModel(1, "删除成功！");
            }
            catch (Exception ex)
            {
                //写入日志

                //返回异常信息
                return OperateContext.Current.JsonModel(0, string.Format("删除失败，{0}", ex.Message));
            }
        }
        #endregion

        #region 07.修改——加载视图
        /// <summary>
        /// 修改栏目
        /// </summary>
        /// <param name="id">栏目Id</param>
        /// <returns>修改视图</returns>
        public ActionResult Edit(int id)
        {
            Model.ChannelView model = ChannelBll.GetModel(id).ToViewModel();
            //根据栏目Id查询上级栏目的名称，并赋值给ViewBag
            Model.Channel pModel = ChannelBll.GetModel(model.PId);
            ViewBag.PName = pModel == null ? System.Configuration.ConfigurationManager.AppSettings["CompanyName"] : pModel.ChannelName;
            return View(model);
        }
        #endregion

        #region 08.修改——提交修改
        /// <summary>
        /// 提交修改
        /// </summary>
        /// <param name="model">视图模型</param>
        /// <returns>JsonModel</returns>
        public ActionResult EditConfirm(Model.ChannelView model)
        {
                //校验模型
                if (ModelState.IsValid)
                {
                    //1.将用户提交的视图模型转换为数据模型
                    Model.Channel dataModel = model.ToDataModel();
                    //2.执行修改操作
                    if (ChannelBll.Update(dataModel))
                    {
                        return OperateContext.Current.JsonModel(1, "修改成功！");
                    }
                    else
                    {
                        return OperateContext.Current.JsonModel(0, "修改失败，请重试！");
                    } 
                }
                else    //模型校验失败
                {
                    return OperateContext.Current.JsonModel(0, "您输入的数据有误，请重试！");
                }
        }
        #endregion

        #region 09.获取模板文件夹内容方法
        /// <summary>
        /// 获取模板文件夹内容方法
        /// </summary>
        /// <returns>模板文件夹树形列表</returns>
        public ActionResult GetTemplatePath()
        {
            string directory = string.Empty;
            StringBuilder html = new StringBuilder();
            if (string.IsNullOrEmpty(Request["dir"]))
            {
                directory = Server.MapPath(Request["dir[]"]);
            }
            else
            {
                directory = Server.MapPath(Request["dir"]);
            }
            DirectoryInfo dirInfo = new DirectoryInfo(directory);
            html.Append("<ul class='jqueryFileTree' style='display: none;'>");
            foreach (DirectoryInfo child in dirInfo.GetDirectories())
            {
                html.Append(string.Format("<li class='directory collapsed'><a href='#' rel='/{0}{1}/'>{2}</a></li>", this.ToRelativePath(directory), child.Name, child.Name));
            }

            foreach (FileInfo file in dirInfo.GetFiles())
            {
                string ext = file.Extension.Substring(1).ToLower();
                html.Append(string.Format("<li class='file ext_{0}'><a href='#' rel='/{1}{2}'>{3}</a></li>", ext, this.ToRelativePath(directory), file.Name, file.Name));
            }
            html.Append("</ul>");

            return Content(html.ToString());
        }
        #endregion
    }
}
